{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# 1 - Fixed-Tilt Yearly Results\n", "\n", "This jupyter journal will walk us through the creation of the most basic fixed-tilt simulation possible with bifacial_radiance.\n", "We will simulate a 1-up landscape system over a white rooftop.\n", "\n", "Steps include:\n", "\n", "\n", "1. Create a folder for your simulation, and Load bifacial_radiance \n", "2. Create a Radiance Object \n", "3. Set the Albedo \n", "4. Download Weather Files \n", "5. Generate the Sky \n", "6. Define a Module type \n", "7. Create the scene \n", "8. Combine Ground, Sky and Scene Objects \n", "9. Analyze and get results \n", "10. Visualize scene options \n", "\n" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Working on a Windows 10\n", "Python version 3.11.8 | packaged by conda-forge | (main, Feb 16 2024, 20:40:50) [MSC v.1937 64 bit (AMD64)]\n", "Pandas version 2.2.3\n", "bifacial_radiance version 0.5.0b2.dev0+gedd68cb.d20250513\n" ] } ], "source": [ "# This information helps with debugging and getting support :)\n", "import sys, platform\n", "import pandas as pd\n", "import bifacial_radiance as br\n", "print(\"Working on a \", platform.system(), platform.release())\n", "print(\"Python version \", sys.version)\n", "print(\"Pandas version \", pd.__version__)\n", "print(\"bifacial_radiance version \", br.__version__)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "## 1. Create a folder for your simulation, and load bifacial_radiance \n", "\n", "First let's set the folder where the simulation will be saved. By default, this is the TEMP folder in the bifacial_radiance distribution.\n", "\n", "The lines below find the location of the folder relative to this Jupyter Journa. You can alternatively point to an empty directory (it will open a load GUI Visual Interface) or specify any other directory in your computer, for example:\n", "\n", "***testfolder = r'C:\\Users\\sayala\\Documents\\RadianceScenes\\Tutorials\\Journal1'***\n", "\n" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Your simulation will be stored in C:\\Users\\mprillim\\sam_dev\\bifacial_radiance\\bifacial_radiance\\TEMP\\Tutorial_01\n" ] } ], "source": [ "import os\n", "from pathlib import Path\n", "import pandas as pd\n", "\n", "testfolder = Path().resolve().parent.parent / 'bifacial_radiance' / 'TEMP' / 'Tutorial_01'\n", "\n", "# Another option using relative address; for some operative systems you might need '/' instead of '\\'\n", "# testfolder = os.path.abspath(r'..\\..\\bifacial_radiance\\TEMP') \n", "\n", "print (\"Your simulation will be stored in %s\" % testfolder)\n", "\n", "if not os.path.exists(testfolder):\n", " os.makedirs(testfolder)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This will load bifacial_radiance and other libraries from python that will be useful for this Jupyter Journal:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "try:\n", " from bifacial_radiance import *\n", "except ImportError:\n", " raise RuntimeError('bifacial_radiance is required. download distribution')\n", "\n", "import numpy as np" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2. Create a Radiance Object" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "path = C:\\Users\\mprillim\\sam_dev\\bifacial_radiance\\bifacial_radiance\\TEMP\\Tutorial_01\n", "Making path: images\n", "Making path: objects\n", "Making path: results\n", "Making path: skies\n", "Making path: EPWs\n", "Making path: materials\n" ] } ], "source": [ "# Create a RadianceObj 'object' named bifacial_example. no whitespace allowed\n", "demo = RadianceObj('tutorial_1',str(testfolder)) " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This will create all the folder structure of the bifacial_radiance Scene in the designated testfolder in your computer, and it should look like this:\n", "\n", "\n", "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 3. Set the Albedo" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To see more options of ground materials available (located on ground.rad), run this function without any input. " ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Input albedo 0-1, or string from ground.printGroundMaterials().\n", "Alternatively, run setGround after readWeatherData()and setGround will read metdata.albedo if available\n" ] } ], "source": [ "# Input albedo number or material name like 'concrete'. \n", "demo.setGround() # This prints available materials." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If a number between 0 and 1 is passed, it assumes it's an albedo value. For this example, we want a high-reflectivity rooftop albedo surface, so we will set the albedo to 0.62" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Loading albedo, 1 value(s), 0.620 avg\n", "1 nonzero albedo values.\n" ] } ], "source": [ "albedo = 0.62\n", "demo.setGround(albedo)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 4. Download and Load Weather Files\n", "\n", "There are various options provided in bifacial_radiance to load weatherfiles. getEPW is useful because you just set the latitude and longitude of the location and it donwloads the meteorologicla data for any location. " ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Getting weather file: USA_VA_Richmond.724010_TMY2.epw\n", " ... OK!\n" ] } ], "source": [ "# Pull in meteorological data using pyEPW for any global lat/lon\n", "epwfile = demo.getEPW(lat = 37.5, lon = -77.6) # This location corresponds to Richmond, VA." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The downloaded EPW will be in the EPWs folder.\n", "\n", "To load the data, use readWeatherFile. This reads EPWs, TMY meterological data, or even your own data as long as it follows TMY data format (With any time resoultion)." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "8760 line in WeatherFile. Assuming this is a standard hourly WeatherFile for the year for purposes of saving Gencumulativesky temporary weather files in EPW folder.\n", "Coercing year to 2001\n", "Saving file EPWs\\metdata_temp.csv, # points: 8760\n", "Calculating Sun position for Metdata that is right-labeled with a delta of -30 mins. i.e. 12 is 11:30 sunpos\n" ] } ], "source": [ "# Read in the weather data pulled in above. \n", "metdata = demo.readWeatherFile(epwfile, coerce_year=2001) " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 5. Generate the Sky.\n", "\n", "Sky definitions can either be for a single time point with gendaylit function,\n", "or using gencumulativesky to generate a cumulativesky for the entire year.\n" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Loaded EPWs\\metdata_temp.csv\n", "message: Error! Solar altitude is -7 < -6 degrees and Idh = 13 > 10 W/m^2 on day 76 !Ibn is 0. Attempting to continue!\n", "Error! Solar altitude is -7 < -6 degrees and Idh = 11 > 10 W/m^2 on day 78 !Ibn is 0. Attempting to continue!\n", "Error! Solar altitude is -6 < -6 degrees and Idh = 14 > 10 W/m^2 on day 81 !Ibn is 0. Attempting to continue!\n", "There were 4537 sun up hours in this climate file\n", "Total Ibh/Lbh: 0.000000\n" ] } ], "source": [ "fullYear = True\n", "if fullYear:\n", " demo.genCumSky() # entire year.\n", "else:\n", " timeindex = metdata.datetime.index(pd.to_datetime('2001-06-17 12:0:0 -7'))\n", " demo.gendaylit(timeindex) # Noon, June 17th (timepoint # 4020)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The method gencumSky calculates the hourly radiance of the sky hemisphere by dividing it into 145 patches. Then it adds those hourly values to generate one single cumulative sky. Here is a visualization of this patched hemisphere for Richmond, VA, US. Can you deduce from the radiance values of each patch which way is North?\n", "\n", "\n", "\n", "Answer: Since Richmond is in the Northern Hemisphere, the modules face the south, which is where most of the radiation from the sun is coming. The north in this picture is the darker blue areas." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 6. DEFINE a Module type\n", "\n", "You can create a custom PV module type. In this case we are defining a module named \"test-module\", in landscape. The x value defines the size of the module along the row, so for landscape modules x > y. This module measures y = 0.984 x = 1.695. \n", "\n", "\n", "
| \n", " | x | \n", "y | \n", "z | \n", "rearZ | \n", "mattype | \n", "rearMat | \n", "Wm2Front | \n", "Wm2Back | \n", "Back/FrontRatio | \n", "
|---|---|---|---|---|---|---|---|---|---|
| 0 | \n", "0.0 | \n", "-0.391 | \n", "0.238 | \n", "0.216 | \n", "a9.3.a0.test-module.6457 | \n", "a9.3.a0.test-module.2310 | \n", "1630394.0 | \n", "435239.3 | \n", "0.267 | \n", "
| 1 | \n", "0.0 | \n", "-0.294 | \n", "0.255 | \n", "0.233 | \n", "a9.3.a0.test-module.6457 | \n", "a9.3.a0.test-module.2310 | \n", "1630987.0 | \n", "330362.8 | \n", "0.203 | \n", "
| 2 | \n", "0.0 | \n", "-0.197 | \n", "0.272 | \n", "0.250 | \n", "a9.3.a0.test-module.6457 | \n", "a9.3.a0.test-module.2310 | \n", "1631598.0 | \n", "260892.0 | \n", "0.160 | \n", "
| 3 | \n", "0.0 | \n", "-0.101 | \n", "0.289 | \n", "0.267 | \n", "a9.3.a0.test-module.6457 | \n", "a9.3.a0.test-module.2310 | \n", "1632208.0 | \n", "218605.1 | \n", "0.134 | \n", "
| 4 | \n", "0.0 | \n", "-0.004 | \n", "0.306 | \n", "0.284 | \n", "a9.3.a0.test-module.6457 | \n", "a9.3.a0.test-module.2310 | \n", "1632819.0 | \n", "206471.0 | \n", "0.126 | \n", "
| 5 | \n", "-0.0 | \n", "0.093 | \n", "0.323 | \n", "0.302 | \n", "a9.3.a0.test-module.6457 | \n", "a9.3.a0.test-module.2310 | \n", "1633430.0 | \n", "212833.6 | \n", "0.130 | \n", "
| 6 | \n", "-0.0 | \n", "0.190 | \n", "0.340 | \n", "0.319 | \n", "a9.3.a0.test-module.6457 | \n", "a9.3.a0.test-module.2310 | \n", "1634041.0 | \n", "233727.4 | \n", "0.143 | \n", "
| 7 | \n", "-0.0 | \n", "0.287 | \n", "0.357 | \n", "0.336 | \n", "a9.3.a0.test-module.6457 | \n", "a9.3.a0.test-module.2310 | \n", "1635704.0 | \n", "277579.4 | \n", "0.170 | \n", "
| 8 | \n", "-0.0 | \n", "0.384 | \n", "0.374 | \n", "0.353 | \n", "a9.3.a0.test-module.6457 | \n", "a9.3.a0.test-module.2310 | \n", "1635450.0 | \n", "327750.6 | \n", "0.200 | \n", "